﻿using System;
using System.Configuration;
using System.Linq;
using System.Net.Mail;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using Beeldbankmvc.Code;
using Beeldbankmvc.Models;
using Beeldbankmvc.ViewModels;
using BeeldbankMVCTools;

namespace Beeldbankmvc.Controllers
{
    [HandleErrorWithELMAH]
    public class MediaObjectController : Controller
    {
        ReactionRepository reactionRepository = new ReactionRepository();
        MediaObjectRepository mediaObjectRepository = new MediaObjectRepository();
        SettingsRepository settingsRepository = new SettingsRepository();
        UserRepository userRepository = new UserRepository();

        //
        // GET: /MediaItem/
        [Authorize(Roles = "Administrator,Beheerder,EindRedacteur")]
        public ActionResult Index()
        {
            return View();
        }

        [Authorize(Roles = "Administrator")]
        public ActionResult Merge(int id)
        {
            BEELDBANK_MEDIAOBJECT mediaObjectSource = mediaObjectRepository.FindOne(id);
            BEELDBANK_MEDIAOBJECT mediaObjectTarget = mediaObjectRepository.FindNextByTitle(mediaObjectSource.Titel, id);
            if (mediaObjectTarget != null)
            {
                mediaObjectRepository.UpdateDescription(mediaObjectTarget.Id, mediaObjectSource.Omschrijving);

                // clear search page output caching
                HttpResponse.RemoveOutputCacheItem("/Search");

                try
                {
                    // Delete all files related to this mediaObjectSource
                    MediaObjectModel mediaObjectModel = new MediaObjectModel(mediaObjectSource);
                    mediaObjectModel.DeleteFiles();

                    // Delete the media object
                    mediaObjectRepository.Delete(mediaObjectSource);
                    mediaObjectRepository.Save();

                    return RedirectToAction("Index", "Search");
                }
                catch
                {
                    return View();
                }
            }
            else
                return RedirectToAction("Index", "Search");
        }

        // TODO: check if this beheerder is the owner
        // GET: /PriceInfo/Delete/5
        [Authorize(Roles = "Administrator,Beheerder,EindRedacteur")]
        public ActionResult Delete(int id)
        {
            BEELDBANK_MEDIAOBJECT mediaObject = mediaObjectRepository.FindOne(id);

            // clear search page output caching
            HttpResponse.RemoveOutputCacheItem("/Search");

            try
            {
                // Delete all files related to this mediaobject
                MediaObjectModel mediaObjectModel = new MediaObjectModel(mediaObject);
                mediaObjectModel.DeleteFiles();

                // Delete the media object
                mediaObjectRepository.Delete(mediaObject);
                mediaObjectRepository.Save();

                return RedirectToAction("Index", "Search");
            }
            catch
            {
                return RedirectToAction("Error", "Home");
            }
        }

        [Authorize(Roles = "Administrator,Beheerder,EindRedacteur")]
        public ActionResult Create(int mediaTypeId)
        {
            MembershipUser currentUser = Membership.GetUser();

            BEELDBANK_MEDIAOBJECT mediaObject = new BEELDBANK_MEDIAOBJECT();

            // set several default values
            mediaObject.TypeId = mediaTypeId;
            mediaObject.Datum_Realisatie = Convert.ToDateTime("01-01-1900");
            mediaObject.FileNummer = settingsRepository.GetFileNumber();
            mediaObject.createdby = currentUser.UserName;
            mediaObject.createdat = DateTime.Now;
            mediaObject.modifiedby = currentUser.UserName;
            mediaObject.modifiedat = DateTime.Now;

            return View(new MediaObjectViewModel(mediaObject));
        }

        //
        // POST: /MediaObject/Create
        [HttpPost]
        [Authorize(Roles = "Administrator,Beheerder,EindRedacteur")]
        public ActionResult Create(FormCollection collection, BEELDBANK_MEDIAOBJECT mediaObject)
        {
            // clear search page output caching
            HttpResponse.RemoveOutputCacheItem("/Search");

            switch (collection["submit"].ToLower())
            {
                case "opslaan":
                case "create":
                    {
                        if (ModelState.IsValid)
                        {
                            MembershipUser currentUser = Membership.GetUser();

                            MediaObjectModel mediaObjectModel = new MediaObjectModel(mediaObject);
                            mediaObjectModel.fillAndSaveMediaObjectModel(Request, currentUser.UserName);

                            //
                            // Read the status information, if the status is 'Ready for publish', send it to publisher (redacteur)
                            //
                            if (collection["Statuses"] != null)
                            {
                                if (collection["Statuses"].ToLower().Equals(ConfigurationManager.AppSettings["readyForPublish"])) // 23717 = ready for publish
                                {
                                    // determain which publisher belongs to the current user
                                    Guid GuidByName = userRepository.FindOnesGuidByName(currentUser.UserName);
                                    MailAddress publisherEmailAddress = userRepository.FindOnesPublisherByName(GuidByName);
                                    if (publisherEmailAddress != null)
                                        Notification.newRequestForPublishingMediaObject(publisherEmailAddress, mediaObject.Id);
                                }
                            }

                            // Navigate back to Edit page
                            return RedirectToAction("Edit", new { id = mediaObject.Id });

                        }
                        else
                            return View(new MediaObjectViewModel(mediaObject));
                    }
            }
            return View(new MediaObjectViewModel(mediaObject));
        }

        [Authorize(Roles = "Administrator,Beheerder,EindRedacteur")]
        public ActionResult Reaction(int id, int? reactionId)
        {
            MembershipUser currentUser = Membership.GetUser();

            BEELDBANK_MEDIAOBJECT mediaObject = mediaObjectRepository.FindOne(id);

            // Prevent errors when specifying the wrong id for editing
            if (mediaObject == null)
                return RedirectToAction("Index", "Search");

            // access on Role, when a role was specified for the media object, membership of this role gives access to the edit media object
            bool accessByRole = false;
            if (mediaObject.GroepRechten != null)
                if (Roles.IsUserInRole(mediaObject.GroepRechten))
                    accessByRole = true;

            /// Check if the current user has permission to edit this item
            /// If not: redirect him to the 'EditNotAllowed' page
            if ((Roles.IsUserInRole("Administrator")) || Roles.IsUserInRole("EindRedacteur") || accessByRole || (mediaObject.modifiedby.ToLower() == currentUser.UserName.ToLower()) || (mediaObject.createdby.ToLower() == currentUser.UserName.ToLower()))
            {
                MediaObjectViewModel mediaObjectViewModel = new MediaObjectViewModel(mediaObject);
                return View(mediaObjectViewModel);
            }
            else
                return RedirectToAction("EditNotAllowed");
        }

        [HttpPost]
        [ValidateInput(false)]
        [Authorize(Roles = "Administrator,Beheerder,EindRedacteur")]
        public ActionResult Reaction(int id, FormCollection collection)
        {
            var mediaObject = mediaObjectRepository.FindOne(id);

            /// Check if the current user has permission to edit this item
            /// If not: redirect him to the 'EditNotAllowed' page
            MembershipUser currentUser = Membership.GetUser();
            bool hasGroupRights = false;
            if (mediaObject.GroepRechten != null)
                hasGroupRights = Roles.IsUserInRole(mediaObject.GroepRechten);

            if (!Roles.IsUserInRole("Administrator") && !hasGroupRights && !Roles.IsUserInRole("EindRedacteur"))
                if ((Roles.IsUserInRole("Beheerder") && (mediaObject.modifiedby.ToLower() != currentUser.UserName.ToLower() && mediaObject.createdby.ToLower() != currentUser.UserName.ToLower())) || !Roles.IsUserInRole("Beheerder"))
                    return RedirectToAction("EditNotAllowed");

            if (ModelState.IsValid)
            {
                var mailInfo = reactionRepository.getmailInformation(Convert.ToInt32(collection["reactionId"]));

                mailInformation reactionMailAddress = mailInfo.FirstOrDefault();

                MailAddress recipientAddress = new MailAddress(reactionMailAddress.toEmail, reactionMailAddress.toName);

                //
                // Read the rated reaction form
                //
                if (collection["submit"].ToLower().Equals("afgehandeld"))
                {
                    reactionRepository.updateMediaObjectReactionStatus(Convert.ToInt32(collection["reactionId"]), Convert.ToInt32(collection["reaction"]));
                    Notification.reactionOnMediaResponse(recipientAddress, "Verwerkt", mediaObject.Id);
                }

                return RedirectToAction("Reaction", new { id = mediaObject.Id });
            }
            else
                return View(new MediaObjectViewModel(mediaObject));
        }

        [Authorize(Roles = "Administrator,Beheerder,EindRedacteur")]
        public ActionResult Edit(int id)
        {
            MembershipUser currentUser = Membership.GetUser();

            BEELDBANK_MEDIAOBJECT mediaObject = mediaObjectRepository.FindOne(id);

            // Prevent errors when specifying the wrong id for editing
            if (mediaObject == null)
                return RedirectToAction("Index", "Search");

            // access on Role, when a role was specified for the media object, membership of this role gives access to the edit media object
            bool accessByRole = false;
            if (mediaObject.GroepRechten != null)
                if (Roles.IsUserInRole(mediaObject.GroepRechten))
                    accessByRole = true;

            /// Check if the current user has permission to edit this item
            /// If not: redirect him to the 'EditNotAllowed' page
            if ((Roles.IsUserInRole("Administrator")) || Roles.IsUserInRole("EindRedacteur") || accessByRole || (mediaObject.modifiedby.ToLower() == currentUser.UserName.ToLower()) || (mediaObject.createdby.ToLower() == currentUser.UserName.ToLower()))
            {
                MediaObjectViewModel mediaObjectViewModel = new MediaObjectViewModel(mediaObject);

                //
                // Correct Description and Title
                //
                string ErrorString = "";
                mediaObject.Omschrijving = MediaObjectTools.CorrectString(mediaObject.Omschrijving, true, ErrorString);
                mediaObject.Titel = MediaObjectTools.CorrectString(mediaObject.Titel, false, ErrorString);

                if (String.IsNullOrEmpty(mediaObject.AltTekst))
                    mediaObject.AltTekst = AppHelper.convertHtmlStringToAltTag(mediaObject);

                //
                // refill temp data object
                //
                #region searchSession
                searchParameters parameters = (searchParameters)TempData["resultSearchCriteria"];
                TempData["resultSearchCriteria"] = parameters;

                string resultType = (String)TempData["resultIdType"];
                string resultList = (String)TempData["resultIdList"];

                if (String.IsNullOrEmpty(resultList))
                {
                    resultList = Request.QueryString["resultList"];
                    resultType = Request.QueryString["resultType"];
                }

                if (!String.IsNullOrEmpty(resultList))
                {
                    string[] resultListParts = resultList.Split(',');
                    int currentIndex = Array.IndexOf(resultListParts, Convert.ToString(id));
                    TempData["resultIdList"] = resultList;

                    if (!String.IsNullOrEmpty(resultType))
                    {
                        TempData["resultIdType"] = resultType;
                        if (parameters != null)
                            mediaObjectViewModel.hasSearchResults = true;

                        if (currentIndex >= 1)
                            mediaObjectViewModel.hasPreviousPage = true;
                        else
                            mediaObjectViewModel.hasPreviousPage = false;

                        if (currentIndex < resultListParts.Length - 1)
                            mediaObjectViewModel.hasNextPage = true;
                        else
                            mediaObjectViewModel.hasNextPage = false;
                    }
                }
                #endregion

                return View(mediaObjectViewModel);
            }
            else
                return RedirectToAction("EditNotAllowed");
        }

        [HttpPost]
        [ValidateInput(false)]
        [Authorize(Roles = "Administrator,Beheerder,EindRedacteur")]
        public ActionResult Edit(int id, FormCollection collection)
        {
            var mediaObject = mediaObjectRepository.FindOne(id);

            /// Check if the current user has permission to edit this item
            /// If not: redirect him to the 'EditNotAllowed' page
            MembershipUser currentUser = Membership.GetUser();
            bool hasGroupRights = false;
            if (mediaObject.GroepRechten != null)
                hasGroupRights = Roles.IsUserInRole(mediaObject.GroepRechten);

            if (!Roles.IsUserInRole("Administrator") && !hasGroupRights && !Roles.IsUserInRole("EindRedacteur"))
                if ((Roles.IsUserInRole("Beheerder") && (mediaObject.modifiedby.ToLower() != currentUser.UserName.ToLower() && mediaObject.createdby.ToLower() != currentUser.UserName.ToLower())) || !Roles.IsUserInRole("Beheerder"))
                    return RedirectToAction("EditNotAllowed");

            // refill temp data object
            #region searchSession
            searchParameters parameters = (searchParameters)TempData["resultSearchCriteria"];
            TempData["resultSearchCriteria"] = parameters;

            string resultList = (String)TempData["resultIdList"];
            int currentIndex = 0;
            string[] resultListParts = { };
            if (!String.IsNullOrEmpty(resultList))
            {
                resultListParts = resultList.Split(',');
                currentIndex = Array.IndexOf(resultListParts, Convert.ToString(id));
                TempData["resultIdList"] = resultList;
            }

            string resultType = (String)TempData["resultIdType"];
            if (!String.IsNullOrEmpty(resultType))
            {
                TempData["resultIdType"] = resultType;
            }
            #endregion

            string s = collection["submit"].ToLower();

            switch (collection["submit"].ToLower())
            {
                case "volgende":
                    {
                        if (currentIndex + 1 > resultListParts.Length)
                        {
                            // if array would be out of bound, navigate to current page
                            return RedirectToAction("Edit", new { id = id });
                        }
                        else
                        {
                            return RedirectToAction("Edit", new { id = resultListParts[currentIndex + 1] });
                        }
                    }
                case "vorige":
                    {
                        if (currentIndex - 1 < 0 || currentIndex - 1 > resultListParts.Length)
                        {
                            // if array would be out of bound, navigate to current page
                            return RedirectToAction("Edit", new { id = id });
                        }
                        else
                        {
                            return RedirectToAction("Edit", new { id = resultListParts[currentIndex - 1] });
                        }
                    }
                case "resultaten":
                    return RedirectToAction("Index", "Search", new { SearchCriteria = parameters.SearchCriteria, displayMode = parameters.displayMode, fromDate = parameters.fromDate, fromDateCheck = parameters.fromDateCheck, toDate = parameters.toDate, toDateCheck = parameters.toDateCheck, OrderBy = parameters.OrderBy, page = parameters.page, typeAnaloog = parameters.typeAnaloog, typeDigitaal = parameters.typeDigitaal, typeVideoAnimation = parameters.typeVideoAnimation, typeMapIllustration = parameters.typeMapIllustration, collectionId = parameters.collectionId, onlyMyItems = parameters.onlyMyItems, statusId = parameters.statusId, showInternalItems = parameters.showInternalItems });
                case "toon object":
                    return RedirectToAction("Details", new { id = id });
                case "verwijderen":
                    // clear search page output caching
                    HttpResponse.RemoveOutputCacheItem("/Search");

                    return RedirectToAction("Delete", new { id = id });
                case "<= 90":
                    // clear search page output caching
                    HttpResponse.RemoveOutputCacheItem("/Search");

                    if (ModelState.IsValid)
                    {
                        MediaObjectModel mediaObjectModel = new MediaObjectModel(mediaObject);

                        mediaObjectModel.rotateMediaObject(id, Request, 270);

                        mediaObjectRepository.GetDataContext().SubmitChanges();
                    }

                    return RedirectToAction("Edit", new { id = id });
                case "90 =>":
                    // clear search page output caching
                    HttpResponse.RemoveOutputCacheItem("/Search");

                    if (ModelState.IsValid)
                    {
                        MediaObjectModel mediaObjectModel = new MediaObjectModel(mediaObject);

                        mediaObjectModel.rotateMediaObject(id, Request, 90);

                        mediaObjectRepository.GetDataContext().SubmitChanges();
                    }

                    return RedirectToAction("Edit", new { id = id });
                case "kopie opslaan":
                    // clear search page output caching
                    HttpResponse.RemoveOutputCacheItem("/Search");

                    if (ModelState.IsValid)
                    {
                        BEELDBANK_MEDIAOBJECT mediaObjectNew = new BEELDBANK_MEDIAOBJECT();

                        // set several default values
                        mediaObjectNew.TypeId = mediaObject.TypeId;
                        mediaObjectNew.Datum_Realisatie = mediaObject.Datum_Realisatie;
                        mediaObjectNew.FileNummer = settingsRepository.GetFileNumber();
                        mediaObjectNew.createdat = DateTime.Now;
                        mediaObjectNew.modifiedat = DateTime.Now;
                        if (!Roles.IsUserInRole("Administrator") && !Roles.IsUserInRole("EindRedacteur"))
                        {
                            mediaObjectNew.createdby = currentUser.UserName;
                            mediaObjectNew.modifiedby = currentUser.UserName;
                        }
                        else
                        {
                            mediaObjectNew.createdby = mediaObject.createdby;
                            mediaObjectNew.modifiedby = mediaObject.modifiedby;
                        }
                        mediaObjectNew.StatusId = mediaObject.StatusId;
                        mediaObjectNew.GroepRechten = mediaObject.GroepRechten;
                        mediaObjectNew.Lokatie = mediaObject.Lokatie;
                        mediaObjectNew.Latitude = mediaObject.Latitude;
                        mediaObjectNew.Longitude = mediaObject.Longitude;
                        mediaObjectNew.Hoogte = mediaObject.Hoogte;
                        mediaObjectNew.Vervaardiger = mediaObject.Vervaardiger;

                        mediaObjectNew.AltTekst = mediaObject.AltTekst;
                        mediaObjectNew.VideoLengte = mediaObject.VideoLengte;

                        mediaObjectNew.Trefwoorden = mediaObject.Trefwoorden;
                        mediaObjectNew.Collectie = mediaObject.Collectie;
                        mediaObjectNew.Archiefnummer = mediaObject.Archiefnummer;
                        mediaObjectNew.Subnummer = mediaObject.Subnummer;
                        mediaObjectNew.Montage = mediaObject.Montage;
                        mediaObjectNew.Mapnummer = mediaObject.Mapnummer;

                        // Correct Description and Title
                        string ErrorString = "";
                        mediaObjectNew.Omschrijving = MediaObjectTools.CorrectString(mediaObject.Omschrijving, true, ErrorString);
                        mediaObjectNew.Titel = MediaObjectTools.CorrectString(mediaObject.Titel, false, ErrorString);

                        MediaObjectModel mediaObjectModel = new MediaObjectModel(mediaObjectNew);
                        mediaObjectModel.copyAndSaveMediaObjectModel(Request, currentUser.UserName);

                        return RedirectToAction("Edit", new { id = mediaObjectNew.Id });
                    }
                    else
                        return View(new MediaObjectViewModel(mediaObject));
                default:
                    // clear search page output caching
                    HttpResponse.RemoveOutputCacheItem("/Search");

                    if (ModelState.IsValid)
                    {
                        //
                        // Read the status information, if the status is 'Ready for publish', send it to publisher (redacteur)
                        //
                        if (collection["Statuses"] != null)
                        {
                            if (collection["Statuses"].ToLower().Equals(ConfigurationManager.AppSettings["readyForPublish"])) // 23717 = ready for publish
                            {
                                // determine which publisher belongs to the current user
                                Guid GuidByName = userRepository.FindOnesGuidByName(currentUser.UserName);
                                MailAddress publisherEmailAddress = userRepository.FindOnesPublisherByName(GuidByName);
                                if (publisherEmailAddress != null)
                                    Notification.newRequestForPublishingMediaObject(publisherEmailAddress, mediaObject.Id);
                            }
                            else if (collection["Statuses"].ToLower().Equals(ConfigurationManager.AppSettings["rejected"])) //23718 = Rejected
                            {
                                // Send the rejection mail to the lastmodifiedId user
                                Guid GuidByName = userRepository.FindOnesGuidByName(mediaObject.createdby);
                                String createdByEmail = userRepository.FindOnesEmailByName(GuidByName);
                                MailAddress rejectionEmailAddress = new MailAddress(createdByEmail, mediaObject.createdby);
                                if (rejectionEmailAddress != null)
                                    Notification.newRejectionForPublishingMediaObject(rejectionEmailAddress, mediaObject.Id);
                            }
                        }

                        MediaObjectModel mediaObjectModel = new MediaObjectModel(mediaObject);

                        UpdateModel(mediaObjectModel.MediaObject, "MediaObject", collection);
                        mediaObjectModel.fillMediaObjectModel(id, Request, currentUser.UserName);

                        mediaObjectRepository.GetDataContext().SubmitChanges();

                        // Navigate back to Edit page
                        return RedirectToAction("Edit", new { id = mediaObject.Id });
                    }
                    else
                        return View(new MediaObjectViewModel(mediaObject));
            }
        }

        [Authorize(Roles = "Beheerder")]
        public ActionResult EditNotAllowed()
        {
            return View();
        }

        [Authorize(Roles = "Beheerder")]
        public ActionResult EditRWSOnly()
        {
            return View();
        }

        public ActionResult FullPage(int id, string type)
        {
            var mediaObject = mediaObjectRepository.FindOne(id);
            MediaObjectViewModel mediaObjectViewModel = new MediaObjectViewModel(mediaObject);
            return View(mediaObjectViewModel);
        }

        [Authorize(Roles = "Administrator, Beheerder, EindRedacteur, Gebruiker")]
        public ActionResult DetailsInternal(string id)
        {
            return RedirectToAction("Details", "MediaObject", new { id = id });
        }

        public ActionResult Details(string id)
        {

            int resolvedId = 0;
            BEELDBANK_MEDIAOBJECT mediaObject = null;

            // access control
            MembershipUser currentUser = Membership.GetUser();

            try
            {
                resolvedId = Utility.getIdFromTitle(id);
                mediaObject = mediaObjectRepository.FindOne(resolvedId);

                ViewData["openGraphTitle"] = mediaObject.Titel;
                ViewData["openGraphImage"] = mediaObject.Id;
                ViewData["openGraphDescription"] = mediaObject.Omschrijving;
                ViewData["openGraphUrl"] = "https://beeldbank.rws.nl/MediaObject/Details/" + mediaObject.Id;

                // Check if mediaobject is an external object or not
                if ((mediaObject.StatusId != Constants.ITEM_STATUS_EXTERN) && (mediaObject.StatusId != Constants.ITEM_STATUS_NEW_UNKNOWN) && (mediaObject.StatusId != Constants.ITEM_STATUS_EDIT_UNKNOWN))
                {
                    if (currentUser == null)
                        // User is not logged on
                        return RedirectToAction("DetailsInternal", "MediaObject", new { id = id });
                    else
                    {
                        if (!Roles.IsUserInRole("Administrator"))
                            if (!currentUser.Email.EndsWith("@rws.nl"))
                                return RedirectToAction("EditRWSOnly");
                    }
                }
            }
            catch
            {
            }

            // Prevent errors when specifying the wrong id for viewing
            if (mediaObject == null)
                return RedirectToAction("Index", "Search");

            // display non static dropdown boxes 

            MediaObjectViewModel mediaObjectViewModel = new MediaObjectViewModel(mediaObject);
            PriceInfoRepository priceInfoRepository = new PriceInfoRepository();
            GebiedRepository gebiedRepository = new GebiedRepository();

            var allAvailableTypes = priceInfoRepository.FindAvailableTypes(mediaObject.TypeId);
            if (allAvailableTypes.Distinct().Count() == 1)
            {
                String onlyAvailableType = allAvailableTypes.ToList().First().Name;
                mediaObjectViewModel.AvailableTypes = new SelectList(allAvailableTypes, "Name", "Name", onlyAvailableType);

                var allAvailableFormats = priceInfoRepository.FindAvailableFormats(mediaObject.TypeId, onlyAvailableType);
                mediaObjectViewModel.AvailableFormats = new SelectList(allAvailableFormats, "Name", "Name");

                mediaObjectViewModel.updateFinishing(onlyAvailableType);
            }
            else
                mediaObjectViewModel.AvailableTypes = new SelectList(allAvailableTypes, "Name", "Name", null);

            // Determine if more objects have the same title
            mediaObjectViewModel.MultipleRecordsExistWithCurrentTitle = Roles.IsUserInRole("Administrator") &&
                (mediaObjectRepository.FindCountByTitle(mediaObject.Titel) > 1);

            mediaObjectViewModel.CanBeEditedByCurrentUser = false;

            if (currentUser != null)
            {
                if (Roles.IsUserInRole("Administrator"))
                    mediaObjectViewModel.CanBeEditedByCurrentUser = true;
                else
                {
                    if ((Roles.IsUserInRole("Beheerder")) &&
                        ((mediaObjectViewModel.MediaObject.createdby.ToLower() == currentUser.UserName.ToLower()) ||
                            (mediaObjectViewModel.MediaObject.modifiedby.ToLower() == currentUser.UserName.ToLower())))
                        mediaObjectViewModel.CanBeEditedByCurrentUser = true;

                    /// Check if the current user has permission to edit this item for edit button
                    if (mediaObject.GroepRechten != null && mediaObjectViewModel.CanBeEditedByCurrentUser == false)
                        mediaObjectViewModel.CanBeEditedByCurrentUser = Roles.IsUserInRole(mediaObject.GroepRechten);
                }
            }

            // fill reaction fields
            if (currentUser != null)
            {
                // Fetch additional information from user repository
                UserRepository userRepository = new UserRepository();
                EditAccountModel model = userRepository.FindOne(new Guid(currentUser.ProviderUserKey.ToString()));
                if (model != null)
                {
                    ViewData["Email"] = model.Email;
                    ViewData["Name"] = model.FirstName + " " + model.Prepositions + " " + model.LastName;
                    ViewData["Phone"] = model.Phone;
                }
            }

            // refill temp data object
            #region searchSession
            // TODO: write documentation about:
            // refill temp data object
            searchParameters parameters = (searchParameters)TempData["resultSearchCriteria"];
            TempData["resultSearchCriteria"] = parameters;
            #endregion

            #region mapSession

            // Store the selected region form MAP button
            int mapId = 0;
            if (TempData["mapId"] != null)
            {
                mapId = (int)TempData["mapId"];
                TempData["mapId"] = mapId;
            }
            else
            {
                if (mapId == 0)
                {
                    mapId = Convert.ToInt32(Request.QueryString["mapId"]);
                    TempData["mapId"] = mapId;
                }
            }

            // Store the result list and result type
            string resultList = (String)TempData["resultIdList"];
            string resultType = (String)TempData["resultIdType"];

            if (String.IsNullOrEmpty(resultList) && (Request.QueryString.Count > 0))
            {
                if (Request.QueryString["resultType"].Equals("Search"))
                    resultList = Request.QueryString["resultList"];
                else
                {
                    // added check for null value, since e.g. crawlers do not follow the logical path and might not have this value
                    if (Request.QueryString["resultArea"] != null)
                    {
                        string[] temp = Request.QueryString["resultArea"].Split('|');

                        DateTime from = new DateTime();
                        DateTime to = new DateTime();

                        if (!String.IsNullOrEmpty(temp[4]))
                        {
                            from = DateTime.Parse(temp[4]);
                            to = DateTime.Parse(temp[4]).AddYears(1);
                        }
                        else
                        {
                            from = DateTime.Parse("1-1-1899");
                            to = DateTime.Now;
                        }

                        // redo the query to have a list of all locations in the selected region, not just the dots plotted on the map
                        foreach (var location in gebiedRepository.getLocationsFromView(mapId, from, to))
                        {
                            resultList += location.Id + ",";
                        }
                        resultList = resultList.TrimEnd(',');
                    }
                }
            }

            if (String.IsNullOrEmpty(resultType))
                resultType = Request.QueryString["resultType"];
            #endregion

            if (!String.IsNullOrEmpty(resultList))
            {
                string[] resultListParts = resultList.Split(',');
                int currentIndex = Array.IndexOf(resultListParts, Convert.ToString(resolvedId));
                TempData["resultIdList"] = resultList;

                if (!String.IsNullOrEmpty(resultType))
                {
                    TempData["resultIdType"] = resultType;
                    if (parameters != null && resultType.Equals("Search"))
                        mediaObjectViewModel.hasSearchResults = true;
                    if (mapId != 0 && resultType.Equals("Map"))
                        mediaObjectViewModel.hasMapResults = true;

                    if (currentIndex >= 1)
                        mediaObjectViewModel.hasPreviousPage = true;
                    else
                        mediaObjectViewModel.hasPreviousPage = false;

                    if (currentIndex < resultListParts.Length - 1)
                        mediaObjectViewModel.hasNextPage = true;
                    else
                        mediaObjectViewModel.hasNextPage = false;
                }
            }

            return View(mediaObjectViewModel);
        }

        [HttpPost]
        [ValidateInput(false)]
        public ActionResult Details(string id, FormCollection collection, MediaObjectViewModel model)
        {
            if (ModelState.IsValid || collection["submit"].ToLower().Equals("verstuur reactie") != true)
            {
                int resolvedId = Utility.getIdFromTitle(id);
                var mediaObject = mediaObjectRepository.FindOne(resolvedId);
                bool isUnknownImage = false;

                // refill temp data object
                #region searchSession
                searchParameters parameters = (searchParameters)TempData["resultSearchCriteria"];
                TempData["resultSearchCriteria"] = parameters;

                string resultList = (String)TempData["resultIdList"];
                int currentIndex = 0;
                string[] resultListParts = { };
                if (!String.IsNullOrEmpty(resultList))
                {
                    resultListParts = resultList.Split(',');
                    currentIndex = Array.IndexOf(resultListParts, Convert.ToString(resolvedId));
                    TempData["resultIdList"] = resultList;
                }
                string resultType = (String)TempData["resultIdType"];
                if (!String.IsNullOrEmpty(resultType))
                {
                    TempData["resultIdType"] = resultType;
                }
                #endregion

                switch (collection["submit"].ToLower())
                {
                    case "download foto":
                        return RedirectToAction("FullPage", new { id = resolvedId, type = "show" });
                    case "download bron":
                        return RedirectToAction("FullPage", new { id = resolvedId, type = "download" });
                    case "volgende":
                        {
                            if (currentIndex + 1 > resultListParts.Length)
                            {
                                // if array would be out of bound, navigate to current page
                                return RedirectToAction("Details", new { id = id });
                            }
                            else
                            {
                                return RedirectToAction("Details", new { id = resultListParts[currentIndex + 1] });
                            }
                        }
                    case "vorige":
                        {
                            if (currentIndex - 1 < 0 || currentIndex - 1 > resultListParts.Length)
                            {
                                // if array would be out of bound, navigate to current page
                                return RedirectToAction("Details", new { id = id });
                            }
                            else
                            {
                                return RedirectToAction("Details", new { id = resultListParts[currentIndex - 1] });
                            }
                        }
                    case "bestellen":
                        // Unused so default values set here
                        int aantal = 1;
                        String finishing = "scan via FTP";

                        return RedirectToAction("AddToCart", "ShoppingCart", new { id = resolvedId, amount = aantal, type = collection["AvailableTypes"], size = collection["AvailableFormats"], finishing = finishing, MediaTypeId = mediaObject.TypeId });
                    case "resultaten":
                        return RedirectToAction("Index", "Search", new { SearchCriteria = parameters.SearchCriteria, displayMode = parameters.displayMode, fromDate = parameters.fromDate, fromDateCheck = parameters.fromDateCheck, toDate = parameters.toDate, toDateCheck = parameters.toDateCheck, OrderBy = parameters.OrderBy, page = parameters.page, typeAnaloog = parameters.typeAnaloog, typeDigitaal = parameters.typeDigitaal, typeVideoAnimation = parameters.typeVideoAnimation, typeMapIllustration = parameters.typeMapIllustration, collectionId = parameters.collectionId, onlyMyItems = parameters.onlyMyItems, statusId = parameters.statusId, showInternalItems = parameters.showInternalItems });
                    case "kaart":
                        // clear the tempdate resultsList by reading it
                        // would prefer doing this in the gebied controler, action map, but this one is cached so won't always be executed
                        string empty = (String)TempData["resultIdList"];

                        // redirect to the area where you came from
                        return RedirectToAction("Select", "Gebied", new { Id = TempData["mapId"] });
                    case "verstuur reactie":
                        // save reaction to the reaction table
                        ReactionModel reactionModel = new ReactionModel();

                        isUnknownImage = Convert.ToBoolean(collection["IsUnknownImage"]);

                        reactionModel.Category = "1";
                        reactionModel.Email = collection["Email"];
                        reactionModel.Name = collection["Name"];
                        reactionModel.Telephone = collection["Telephone"];
                        reactionModel.Message = collection["Message"];
                        reactionModel.MediaObjectId = resolvedId;
                        reactionModel.MediaObjectEigenaarNaam = mediaObject.modifiedby;

                        if (isUnknownImage)
                        {
                            // Subject: "Zoekplaatje"
                            reactionModel.Subject = "6";
                            reactionModel.MediaObjectTitel = collection["Titel"];
                            reactionModel.MediaObjectOmschrijving = collection["Omschrijving"];
                            reactionModel.MediaObjectLocatie = collection["Locatie"];
                            reactionModel.Message = "";
                        }
                        else
                        {
                            // Subject: "Reactie op media object"
                            reactionModel.Subject = "5";
                        }

                        Guid GuidByName = userRepository.FindOnesGuidByName(mediaObject.modifiedby);
                        reactionModel.MediaObjectEigenaarEmail = userRepository.FindOnesEmailByName(GuidByName);
                        if (String.IsNullOrEmpty(reactionModel.MediaObjectEigenaarEmail))
                            reactionModel.MediaObjectEigenaarEmail = ConfigurationManager.AppSettings["mainRecipientEmail"];

                        if (isUnknownImage)
                            Notification.newDescriptionOnMediaObjectCreated(ConfigurationManager.AppSettings["mainRecipientEmail"], ConfigurationManager.AppSettings["nameMainRecipient"], resolvedId);
                        else
                            Notification.newReactionOnMediaObjectCreated(reactionModel.MediaObjectEigenaarEmail, reactionModel.MediaObjectEigenaarNaam, resolvedId);

                        // save the working version 
                        reactionRepository.AddFirst(reactionModel);
                        reactionRepository.Save();

                        // Redirect to "bedankt voor reactie" page
                        return RedirectToAction("ThankYou");
                    default:
                        // display non static dropdown boxes 
                        MediaObjectViewModel mediaObjectViewModel = new MediaObjectViewModel(mediaObject);
                        PriceInfoRepository priceInfoRepository = new PriceInfoRepository();

                        var allAvailableTypes = priceInfoRepository.FindAvailableTypes(mediaObject.TypeId);
                        mediaObjectViewModel.AvailableTypes = new SelectList(allAvailableTypes, "Name", "Name", collection["AvailableTypes"]);

                        var allAvailableFormats = priceInfoRepository.FindAvailableFormats(mediaObject.TypeId, collection["AvailableTypes"]);
                        mediaObjectViewModel.AvailableFormats = new SelectList(allAvailableFormats, "Name", "Name", collection["AvailableFormats"]);

                        mediaObjectViewModel.updateFinishing(collection["AvailableTypes"]);

                        // paging for the search session
                        #region searchSessionPaging
                        if (!String.IsNullOrEmpty(resultList) && !String.IsNullOrEmpty(resultType))
                        {

                            if (parameters != null)
                            {
                                mediaObjectViewModel.hasSearchResults = true;
                            }
                            if (currentIndex >= 1)
                            {
                                mediaObjectViewModel.hasPreviousPage = true;
                            }
                            else
                            {
                                mediaObjectViewModel.hasPreviousPage = false;
                            }

                            if (currentIndex < resultListParts.Length - 1)
                            {
                                mediaObjectViewModel.hasNextPage = true;
                            }
                            else
                            {
                                mediaObjectViewModel.hasNextPage = false;
                            }
                        }
                        #endregion

                        return View(mediaObjectViewModel);
                }
            }
            else
            {
                int resolvedId = Utility.getIdFromTitle(id);
                var mediaObject = mediaObjectRepository.FindOne(resolvedId);

                // refill temp data object
                #region searchSession
                searchParameters parameters = (searchParameters)TempData["resultSearchCriteria"];
                TempData["resultSearchCriteria"] = parameters;

                string resultList = (String)TempData["resultIdList"];
                int currentIndex = 0;
                string[] resultListParts = { };
                if (!String.IsNullOrEmpty(resultList))
                {
                    resultListParts = resultList.Split(',');
                    currentIndex = Array.IndexOf(resultListParts, Convert.ToString(resolvedId));
                    TempData["resultIdList"] = resultList;
                }
                String resultType = (String)TempData["resultIdType"];
                if (!String.IsNullOrEmpty(resultType))
                {
                    TempData["resultIdType"] = resultType;
                }
                #endregion

                // display non static dropdown boxes 
                #region orderForm
                MediaObjectViewModel mediaObjectViewModel = new MediaObjectViewModel(mediaObject);
                PriceInfoRepository priceInfoRepository = new PriceInfoRepository();

                var allAvailableTypes = priceInfoRepository.FindAvailableTypes(mediaObject.TypeId);
                mediaObjectViewModel.AvailableTypes = new SelectList(allAvailableTypes, "Name", "Name", collection["AvailableTypes"]);

                var allAvailableFormats = priceInfoRepository.FindAvailableFormats(mediaObject.TypeId, collection["AvailableTypes"]);
                mediaObjectViewModel.AvailableFormats = new SelectList(allAvailableFormats, "Name", "Name", collection["AvailableFormats"]);

                mediaObjectViewModel.updateFinishing(collection["AvailableTypes"]);
                #endregion

                // paging for the search session
                #region searchSessionPaging
                if (!String.IsNullOrEmpty(resultList))
                {
                    if (!String.IsNullOrEmpty(resultType))
                    {
                        TempData["resultIdType"] = resultType;
                        if (parameters != null)
                        {
                            mediaObjectViewModel.hasSearchResults = true;
                        }
                        if (currentIndex >= 1)
                        {
                            mediaObjectViewModel.hasPreviousPage = true;
                        }
                        else
                        {
                            mediaObjectViewModel.hasPreviousPage = false;
                        }

                        if (currentIndex < resultListParts.Length - 1)
                        {
                            mediaObjectViewModel.hasNextPage = true;
                        }
                        else
                        {
                            mediaObjectViewModel.hasNextPage = false;
                        }
                    }
                }
                #endregion

                MembershipUser currentUser = Membership.GetUser();
                // fill reaction fields
                if (currentUser != null)
                {
                    // Fetch additional information from user repository
                    EditAccountModel accountModel = userRepository.FindOne(new Guid(currentUser.ProviderUserKey.ToString()));
                    if (model != null)
                    {
                        ViewData["Email"] = mediaObjectViewModel.Email = accountModel.Email;
                        ViewData["Name"] = mediaObjectViewModel.Name = accountModel.FirstName + " " + accountModel.Prepositions + " " + accountModel.LastName;
                        ViewData["Phone"] = mediaObjectViewModel.Telephone = accountModel.Phone;
                    }
                }
                return View(mediaObjectViewModel);
            }
        }

        //
        // GET: /Reaction/ThankYou
        public ActionResult ThankYou()
        {
            return View();
        }

        public ActionResult Counter(int? id)
        {
            if (id.HasValue)
                mediaObjectRepository.IncreaseViewCounter(id.Value, ConfigurationManager.AppSettings["publicationName"]);

            return View();
        }

        [Authorize(Roles = "Administrator")]
        public ActionResult CleanupUnwantedShowInBanner(int? mediaPageIndex)
        {
            FiveStarViewModel fsModel = new FiveStarViewModel();
            fsModel.pageSize = Constants.PAGE_SIZE;
            fsModel.pageIndex = 0;
            if (mediaPageIndex.HasValue)
                fsModel.pageIndex = mediaPageIndex.Value;

            mediaObjectRepository.CleanupUnwantedShowInBanner(fsModel.pageSize, fsModel.pageIndex);
            mediaObjectRepository.Save();

            return RedirectToAction("FiveStarMedia", "MediaObject", new { mediaPageIndex = fsModel.pageIndex });
        }

        [Authorize(Roles = "Administrator")]
        public ActionResult FiveStarMedia(int? mediaPageIndex)
        {
            FiveStarViewModel fsModel = new FiveStarViewModel();
            fsModel.pageSize = Constants.PAGE_SIZE;
            fsModel.pageIndex = 0;
            if (mediaPageIndex.HasValue)
                fsModel.pageIndex = mediaPageIndex.Value;

            fsModel.fiveStarObjects = mediaObjectRepository.getAllFotosWithFiveStars(fsModel.pageSize, fsModel.pageIndex);
            fsModel.numberOfRows = mediaObjectRepository.getAllFotosWithFiveStarsCount();

            return View(fsModel);
        }

        [Authorize(Roles = "Administrator")]
        public ActionResult AddTo5Stars(int mediaObjectId, int? mediaPageIndex)
        {
            MembershipUser currentUser = Membership.GetUser();

            BEELDBANK_MEDIAOBJECT mediaObject = mediaObjectRepository.FindOne(mediaObjectId);

            // Prevent errors when specifying the wrong id for editing
            if (mediaObject == null)
                return RedirectToAction("FiveStarMedia", "MediaObject");

            mediaObjectRepository.AddTo5Stars(mediaObjectId);
            mediaObjectRepository.Save();

            int pageIndex = 0;
            if (mediaPageIndex.HasValue)
                pageIndex = mediaPageIndex.Value;

            return RedirectToAction("FiveStarMedia", "MediaObject", new { mediaPageIndex = pageIndex });
        }

        [Authorize(Roles = "Administrator")]
        public ActionResult RemoveFrom5Stars(int mediaObjectId, int? mediaPageIndex)
        {
            BEELDBANK_MEDIAOBJECT mediaObject = mediaObjectRepository.FindOne(mediaObjectId);

            // Prevent errors when specifying the wrong id for editing
            if (mediaObject == null)
                return RedirectToAction("FiveStarMedia", "MediaObject");

            mediaObjectRepository.RemoveFrom5Stars(mediaObjectId);
            mediaObjectRepository.RemoveFromDisplayInBanner(mediaObjectId);
            mediaObjectRepository.Save();

            int pageIndex = 0;
            if (mediaPageIndex.HasValue)
                pageIndex = mediaPageIndex.Value;

            return RedirectToAction("FiveStarMedia", "MediaObject", new { mediaPageIndex = pageIndex });
        }
    }
}
